package com.zz.admin.auth.extension;

import com.zz.admin.auth.dto.DefaultUserDetails;
import com.zz.admin.userManagement.dto.UserDto;
import com.zz.admin.userManagement.dto.UserRoleMenuDto;
import com.zz.admin.userManagement.service.UserService;
import com.zz.common.constants.RedisKeyConstant;
import com.zz.common.utils.cache.RedisCacheUtils;
import com.zz.common.utils.common.TokenUtils;
import com.zz.common.utils.common.UUIDGenerator;
import jakarta.annotation.Resource;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.*;

@Component
public class OAuth2AuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    @Resource
    private UserService userService;

    @Resource
    private RedisCacheUtils redisCacheUtils;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authentication) throws IOException, ServletException {
        AuthenticationSuccessHandler.super.onAuthenticationSuccess(request, response, chain, authentication);
    }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        // 这里通过OAuth2User来获取用户信息
        OAuth2User oAuth2User = (OAuth2User) authentication.getPrincipal();

        // todo: 策略
        String name = oAuth2User.getName();
        Integer id = oAuth2User.getAttribute("id");
        String login = oAuth2User.getAttribute("login");

        UserDto userDto = userService.insertFromThirdParty(id.toString(), login, name);

        // 生成token返回给前端
        String token = TokenUtils.geneJsonWebToken(userDto.getUserName(), userDto.getUserId());

        // 将用户信息DefaultUserDetails储存在redis中
        List<String> permissions = getAuthorities(userDto.getUserId());
        redisCacheUtils.setCacheObject(RedisKeyConstant.CURRENT_USER + userDto.getUserId(), new DefaultUserDetails(userDto, permissions));

        // 将token存入session
        request.getSession().setAttribute("user_token", token);
        String tokenId = UUIDGenerator.generateUUID();
        request.getSession().setAttribute("token_id_" + tokenId, token);

        // todo: 暂时写死
        response.sendRedirect("http://localhost:9090/layout?token_id=" + tokenId);
    }

    private List<String> getAuthorities(String userId) {
        List<UserRoleMenuDto> userRoleMenuDtos = userService.queryRoleAndMenuByUserId(userId);
        Set<String> res = new HashSet<>();
        for (UserRoleMenuDto userRoleMenuDto : userRoleMenuDtos) {
            String roleCode = userRoleMenuDto.getRoleCode();
            if (StringUtils.isNotBlank(roleCode)) {
                res.add("ROLE_" + roleCode);
            }
            String permissions = userRoleMenuDto.getPermission();
            if (StringUtils.isNotBlank(permissions)) {
                res.addAll(Arrays.asList(permissions.split(";")));
            }
        }
        return new ArrayList<>(res);
    }
}
